#ifndef __DM_PROTOCOL_H__
#define __DM_PROTOCOL_H__


#include <iostream>
#include <cctype>
#include "base_protocol.h"


#define DM_PACKET_HEAD_LEN          20
#define DM_BODY_HEAD_LEN            44

enum DM7REQCMD
{
    DM7_CMD_LOGIN                       = 1,                   
    DM7_CMD_LOGOUT                      = 2,                   
    DM7_CMD_STMT_ALLOCATE               = 3,                  
    DM7_CMD_STMT_FREE                   = 4,                   
    DM7_CMD_PREPARE                     = 5,                   
    DM7_CMD_EXECUTE                     = 6,                    
    DM7_CMD_FETCH                       = 7,                    
    DM7_CMD_COMMIT                      = 8,                   
    DM7_CMD_ROLLBACK                    = 9,
    DM7_CMD_EXECUTE2                    = 13,
    DM7_CMD_PUT_DATA                    = 14,
    DM7_CMD_GET_DATA                    = 15,
    DM7_CMD_STMT_CLOSE                  = 17,                   
    DM7_CMD_EXPLAIN                     = 21,                   
    DM7_CMD_CURSOR_SET_NAME             = 27,                   
    DM7_CMD_GET_LOB_LEN                 = 29,                   
    DM7_CMD_SET_LOB_DATA                = 30,                   
    DM7_CMD_LOB_TRUNCATE                = 31,                   
    DM7_CMD_GET_LOB_DATA                = 32,                   
    DM7_CMD_MORE_RESULT                 = 44,                    
    DM7_CMD_SESS_ISO                    = 52,
    DM7_CMD_PRE_EXEC                    = 90,
    DM7_CMD_EXEC_DIRECT                 = 91,
    DM7_CMD_TABLE_TS                    = 71,
    DM7_CMD_STARTUP                     = 200,
    DM7_CMD_XA                          = 60
};

enum DM7RSPTYPE
{
    DM7_RSP_OTHER              = 0,    // 0x00,绑定变量,部分命令语句的应答,此时statementid为0
    DM7_RSP_BASE               = 127,  // 0x7F
    DM7_RSP_DDL_CDB            = 128,  // 0x80
    DM7_RSP_DDL_CTAB           = 129,  // 0x81
    DM7_RSP_DDL_DTAB           = 130,  // 0x82
    DM7_RSP_DDL_CVIEW          = 131,  // 0x83
    DM7_RSP_DDL_DVIEW          = 132,  // 0x84
    DM7_RSP_DDL_CIND           = 133,  // 0x85
    DM7_RSP_DDL_DIND           = 134,  // 0x86
    DM7_RSP_DDL_CUSR           = 135,  // 0x87
    DM7_RSP_DDL_DUSR           = 136,  // 0x88
    DM7_RSP_DDL_CROL           = 137,  // 0x89
    DM7_RSP_DDL_DROL           = 138,  // 0x8A
    DM7_RSP_DDL_DROP           = 139,  // 0x8B
    DM7_RSP_DDL_ALTDB          = 140,  // 0x8C
    DM7_RSP_DDL_ALTUSR         = 141,  // 0x8D
    DM7_RSP_DDL_CFUNC          = 142,  // 0x8E
    DM7_RSP_DDL_CPROC          = 143,  // 0x8F
    DM7_RSP_DDL_GRANT          = 144,  // 0x90
    DM7_RSP_DDL_REVOKE         = 145,  // 0x91
    DM7_RSP_DDL_ALTTAB         = 146,  // 0x92
    DM7_RSP_COMMIT             = 147,  // 0x93
    DM7_RSP_ROLLBACK           = 148,  // 0x94
    DM7_RSP_EXPLAIN            = 149,  // 0x95
    DM7_RSP_SET_TRAN           = 150,  // 0x96
    DM7_RSP_SAVEPNT            = 151,  // 0x97
    DM7_RSP_SET_CURDB          = 152,  // 0x98
    DM7_RSP_SET_CURSCH         = 153,  // 0x99
    DM7_RSP_LOCK_TAB           = 154,  // 0x9A
    DM7_RSP_DDL_AUDIT          = 155,  // 0x9B
    DM7_RSP_DML_INSERT         = 157,  // 0x9D
    DM7_RSP_DML_DELETE         = 158,  // 0x9E
    DM7_RSP_DML_UPDATE         = 159,  // 0x9F
    DM7_RSP_DML_SELECT         = 160,  // 0xA0
    DM7_RSP_DML_SELECT_INTO    = 161,  // 0xA1
    DM7_RSP_DML_CALL           = 162,  // 0xA2
    DM7_RSP_LOGIN              = 163,  // 0xA3
    DM7_RSP_SET_TIME_ZONE      = 165,  // 0xA5
    DM7_RSP_SET_SESS_TRAN      = 166,  // 0xA6
    DM7_RSP_FETCH_NOT_OVER     = 167,  // 0xA7
    DM7_RSP_EXEC_PROC          = 178,  // 0xB2
    DM7_RSP_SIMPLE             = 187,  // 0xBB
    DM7_RSP_DDL_CSCHEMA        = 188,  // 0xBC
    DM7_RSP_PLAN_ERRCODE       = 189,  // 0xBD
    DM7_RSP_DDL_ALTTRIG        = 190,  // 0xBE
    DM7_RSP_DDL_DROP_TABLE     = 191,  // 0xBF
    DM7_RSP_DDL_DROP_INDEX     = 192,  // 0xC0
    DM7_RSP_DDL_DROP_VIEW      = 193,  // 0xC1
    DM7_RSP_DML_TRCT           = 194,  // 0xC2
    DM7_RSP_SET_IDENTINS       = 195,  // 0xC3
    DM7_RSP_DDL_CSEQ           = 196,  // 0xC4
    DM7_RSP_DML_CURSOR_DECLARE = 197,  // 0xC5
    DM7_RSP_DML_CURSOR_OPEN    = 198,  // 0xC6
    DM7_RSP_DML_CURSOR_CLOSE   = 199,  // 0xC7
    DM7_RSP_DML_CURSOR_UPDATE  = 200,  // 0xC8
    DM7_RSP_DML_CURSOR_DELETE  = 201,  // 0xC9
    DM7_RSP_DML_CURSOR_FETCH   = 202,  // 0xCA
    DM7_RSP_DML_CURSOR_SEEK    = 203,  // 0xCB
    DM7_RSP_DDL_CLGN           = 204,  // 0xCC
    DM7_RSP_DDL_ALTLGN         = 205,  // 0xCD
    DM7_RSP_DDL_CCONIND        = 206,  // 0xCE
    DM7_RSP_DDL_DCONIND        = 207,  // 0xCF
    DM7_RSP_DDL_ALTCONIND      = 208,  // 0xD0
    DM7_RSP_STARTUP            = 228   // 0xE4
};


namespace secsmart_protocol
{
    class DMProtocol: public BaseProtocol
    {
        public:
            DMProtocol()
            {
                databaseName = DBNAME_DAMENG;
            }

            virtual DETECT_RESULT parse(secsmart_session::session_sptr session, const uint8_t *buf, size_t size, bool is_forward);

            std::string extendInfo();

        private:
            bool isTrueCmd(int16_t cmdType);
            void parseVersion(const uint8_t *buf,size_t &position, size_t size);
            bool isValidVersion(const std::string &str);


        private:
            std::string versionInfo = "";


    };
}









#endif